Component({
  properties: {
    visible: {
      type: Boolean,
      value: false
    },
    title: {
      type: String,
    },
    step: {
      type: Number,
      value: 1
    },
    desc: {
      type: String,
    },
    queryVal: {
      type: String,
    },
    stroageVal: {
      type: String,
    }
  },

  data: {
    steps: [
      {
        desc: '',
        position: {},
        tipPosition: {}
      }
    ],
    currentStep: 0,
    showMask: true,
    screenWidth: 375,
    screenHeight: 667,
    tipX: 0,
    dynamicSty: {},
    showBtn: false,
  },

  lifetimes: {
    attached() {
      const systemInfo = wx.getSystemInfoSync();
      this.setData({
        screenWidth: systemInfo.windowWidth,
        screenHeight: systemInfo.windowHeight,
        steps: [
          {
            desc: this.properties.desc,
            title: this.properties.title,
            position: {},
            tipPosition: {}
          }
        ]
      });
      setTimeout(res => {
        this.setData({
          showBtn: true
        });
      }, 2000)
    }
  },

  observers: {
    visible(visible) {
      if (visible) {
        this.getTargetPosition();
      }
    }
  },

  ready() {
    // 组件准备好后，如果已经可见，则绘制引导线
    if (this.properties.visible) {
      setTimeout(() => {
        this.getTargetPosition();
      }, 100);
    }
  },

  methods: {
    // 获取目标元素位置
    getTargetPosition() {
      wx.nextTick(() => {
        const targetQuery = wx.createSelectorQuery();
        targetQuery.select(this.properties.queryVal).boundingClientRect();
        targetQuery.exec(res => {
          if (res && res[0]) {
            const position = res[0];
            this.setData({
              ['steps[0].position']: position
            }, () => {
              wx.nextTick(() => {
                const tipQuery = wx.createSelectorQuery().in(this);
                tipQuery.select('#guide-tip').boundingClientRect(rect => {
                  if (rect) {
                    const tipWidth = rect.width;
                    const tipHeight = rect.height;
                    const tipPosition = this.calculateTipPosition(position, tipWidth, tipHeight);
                    tipPosition.width = tipWidth;
                    tipPosition.height = tipHeight;
                    this.setData({
                      ['steps[0].tipPosition']: tipPosition,
                      dynamicSty: tipPosition.dynamicSty
                    });
                    this.drawGuideLine(position, tipPosition);
                  }
                }).exec();
              });
            });
          }
        });
      });
    },

    // 绘制引导线（支付宝风格）
    drawGuideLine(target, tipPosition) {
      const ctx = wx.createCanvasContext('guideLine', this);
      const { screenWidth, screenHeight } = this.data;
      ctx.clearRect(0, 0, screenWidth, screenHeight);

      // 支付宝风格：蓝色实线，更粗，更现代
      ctx.setLineDash([]);
      ctx.setStrokeStyle('#1677ff');
      ctx.setLineWidth(3);
      ctx.setLineCap('round');
      ctx.setLineJoin('round');

      // 目标中心点
      const targetCenterX = target.left + target.width / 2;
      const targetCenterY = target.top + target.height / 2;

      // 提示框位置信息
      const tipCenterX = tipPosition.ox; // 提示框中心X
      const tipCenterY = tipPosition.y2; // 提示框顶部Y（如果在下方）或底部Y（如果在上方）

      // 确定起点位置（从目标边缘出发，不覆盖目标）
      let startX, startY;
      const margin = 15;

      if (tipPosition.placement === 'top') {
        // 提示框在目标下方，从目标底边出发
        startX = targetCenterX;
        startY = target.top + target.height + margin;
      } else {
        // 提示框在目标上方，从目标顶边出发
        startX = targetCenterX;
        startY = target.top - margin;
      }

      // 转折点位置
      const cornerX = tipCenterX;
      const cornerY = startY;

      // 终点位置
      const endX = tipCenterX;
      const endY = tipCenterY;

      // 绘制L型路径
      ctx.beginPath();
      ctx.moveTo(startX, startY);
      ctx.lineTo(cornerX, cornerY);
      ctx.lineTo(endX, endY);
      ctx.stroke();

      // 绘制箭头
      const arrowSize = 10;
      const arrowDirection = tipPosition.placement === 'top' ? 'down' : 'up';

      ctx.beginPath();
      if (arrowDirection === 'down') {
        ctx.moveTo(endX, endY);
        ctx.lineTo(endX - arrowSize / 2, endY - arrowSize);
        ctx.lineTo(endX + arrowSize / 2, endY - arrowSize);
      } else {
        ctx.moveTo(endX, endY);
        ctx.lineTo(endX - arrowSize / 2, endY + arrowSize);
        ctx.lineTo(endX + arrowSize / 2, endY + arrowSize);
      }
      ctx.closePath();
      ctx.setFillStyle('#1677ff');
      ctx.fill();

      // 绘制起点圆点
      ctx.beginPath();
      ctx.arc(startX, startY, 4, 0, 2 * Math.PI);
      ctx.setFillStyle('#1677ff');
      ctx.fill();

      ctx.beginPath();
      ctx.arc(startX, startY, 2, 0, 2 * Math.PI);
      ctx.setFillStyle('#ffffff');
      ctx.fill();

      ctx.draw();
    },

    // 计算提示框位置
    calculateTipPosition(target, tipWidth, tipHeight) {
      const { screenWidth, screenHeight } = this.data;

      const centerY = target.top + target.height / 2;
      const centerX = target.left + target.width / 2;

      // 更稳健的上下放置判断：保留最小边距，避免贴边超出
      const safeMargin = 16;
      let placement = 'top';
      const spaceBelow = screenHeight - (target.top + target.height) - safeMargin;
      const spaceAbove = target.top - safeMargin;
      if (spaceBelow >= tipHeight + 24) {
        placement = 'top'; // 提示框放在目标下方（视觉上更合理）
      } else if (spaceAbove >= tipHeight + 24) {
        placement = 'bottom'; // 放在上方
      } else {
        // 两边都不够，选空间更大的方向，并缩进
        placement = spaceBelow >= spaceAbove ? 'top' : 'bottom';
      }
      const isLeft = centerX < screenWidth / 2;

      let top, left, y, y2, ox, dynamicSty;

      // 提示框上下
      if (placement === 'top') {
        top = Math.min(screenHeight - tipHeight - safeMargin, target.top + target.height + 16);
        y = target.bottom;
        y2 = top;
        dynamicSty = `top:${top}px;`;
      } else {
        top = Math.max(safeMargin, target.top - tipHeight - 16);
        y = target.top;
        y2 = top + tipHeight;
        dynamicSty = `top:${top}px;`;
      }

      // 提示框居中计算
      left = target.left + target.width / 2 - tipWidth / 2;
      left = Math.max(safeMargin, Math.min(left, screenWidth - tipWidth - safeMargin));
      dynamicSty += `left:${left}px;`;

      // 引导线终点 x 坐标（ox）
      ox = left + tipWidth / 2;

      return { top, left, placement, y, y2, ox, dynamicSty };
    },

    // 进入下一步
    nextStep() {
      const { currentStep, steps } = this.data;
      if (currentStep < steps.length - 1) {
        this.setData({
          currentStep: currentStep + 1
        });
      } else {
        this.finish();
      }
    },

    // 完成引导
    finish() {
      wx.setStorageSync(this.properties.stroageVal, true);
      this.triggerEvent('close');
    },

    // 关闭引导
    close() {
      this.triggerEvent('close');
    }
  }
});
